(async function () {
  const modifiedDocuments = await api.runAsyncOnBackendWithManualTransactionHandling(
    async (currentNoteId) => {
      async function getTaskTemplate() {
        return (
          await (await api.getNoteWithLabel("todoTemplates")).getChildNotes()
        ).find((m) => m.hasAttribute("label", "todoItem"));
      }

      async function getTaskCreateScriptNote() {
        return api.getNoteWithLabel("todoTaskCreate");
      }

      async function getCollectionViewsNote() {
        return api.getNoteWithLabel("collectionViews");
      }

      const taskTemplate = await getTaskTemplate();
      const taskCreateScriptNote = await getTaskCreateScriptNote();
      const collectionViewsNote = await getCollectionViewsNote();

      const todos = await api.getNotesWithLabel("todo");

      for await (const todo of todos) {
        api.transactional( async (todo) => {
            if (collectionViewsNote) {
              todo.setRelation("renderNote", collectionViewsNote.noteId);
            }

            const childNotes = (await todo.getChildNotes()).filter(
              (m) =>
                m.hasLabel("todoBacklog") ||
                m.hasLabel("todoDone") ||
                m.hasLabel("todoInProgress")
            );

            for await (const childNote of childNotes) {
              childNote.setRelation("child:template", taskTemplate.noteId);
              childNote.setRelation(
                "runOnChildNoteCreation",
                taskCreateScriptNote.noteId
              );
            }

            const todoItems = await api.searchForNotes(
              "~location and note.ancestors.labels.todo"
            );

            for await (const todoItem of todoItems) {
              todoItem.setRelation("template", taskTemplate.noteId);
            }
        });
      }

      const currentNote = await api.getNote(currentNoteId);
      currentNote.removeLabel("run");
      await currentNote.save();

      return todos.length;
    },
    [api.currentNote.noteId]
  );

  await api.waitUntilSynced();

  if (modifiedDocuments) {
    api.showMessage(`${modifiedDocuments} To Do notes migrated! Good session!`);
  }
})();
